package net.xxcxcxcx.xc_enhancedmob.render;

import net.minecraft.nbt.NbtCompound;
import net.minecraft.util.Identifier;

import java.util.Random;

/**
 * 记录纹理元素在材质上的位置以及纹理的大小
 * <p>并自动运算和处理纹理图片
 */
public class TextureElement {
    private Identifier texture;
    private int width;
    private int height;
    private int texW;
    private int texH;
    //存储方式是AARRGGBB
    private int color = 0xFFFFFFFF;
    private int u;
    private int v;

    /**
     * 嵌套定义纹理
     * <p>需要注意到，在fabric环境下，uv使用像素点位置而非比例位置
     */
    public TextureElement(String resourceLocation, int width, int height) {
        this(resourceLocation, 0, 0, width, height);
    }

    public TextureElement(String resourceLocation, int u, int v, int width, int height) {
        this(resourceLocation, u, v, width, height, width, height);
    }

    public TextureElement(String resourceLocation, int u, int v, int width, int height, int texW, int texH) {
        this.setTexture(new Identifier(resourceLocation));
        this.setWidth(width);
        this.setHeight(height);
        this.setTexW(texW);
        this.setTexH(texH);
        this.setU(u);
        this.setV(v);
    }

    //依据color，随机范围为+-round 的随机
    public TextureElement randomColor(int color, int round) {
        setColor(color);
        if (round <= 0) return this;
        Random random = new Random();
        setRed(getRed() + random.nextInt(round * 2) - round);
        setBlue(getBlue() + random.nextInt(round * 2) - round);
        setGreen(getGreen() + random.nextInt(round * 2) - round);
        return this;
    }

    //完全随机数慎用，配色比较爆炸
    public TextureElement randomColor() {
        Random random = new Random();
        setRed(random.nextInt(256));
        setBlue(random.nextInt(256));
        setGreen(random.nextInt(256));
        return this;
    }

    public int getAlpha() {
        return (color >> 24) & 0xff;
    }

    public TextureElement setAlpha(int alpha) {
        color = color & 0x00ffffff;
        color = color | ((alpha % 256) << 24);
        return this;
    }

    public int getRed() {
        return (color >> 16) & 0xff;
    }

    public TextureElement setRed(int red) {
        color = color & 0xff00ffff;
        color = color | ((red % 256) << 16);
        return this;
    }

    public int getGreen() {
        return (color >> 8) & 0xff;
    }

    public TextureElement setGreen(int green) {
        color = color & 0xffff00ff;
        color = color | ((green % 256) << 8);
        return this;
    }

    public int getBlue() {
        return color & 0xff;
    }

    public TextureElement setBlue(int blue) {
        color = color & 0xffffff00;
        color = color | ((blue % 256));
        return this;
    }

    //获取图片U0坐标为图片最左侧位置
    public float U0() {
        return getU() / (float) getTexW();
    }

    //获取图片U1坐标为图片最右侧，precent为显示比例
    public float U1(float precent) {
        return (getU() + (getWidth() * precent)) / (float) getTexW();
    }

    //获取图片V0坐标为图片最上侧位置
    public float V0() {
        return getV() / (float) getTexH();
    }

    //获取图片V1坐标为图片最下侧，precent为显示比例
    public float V1(float precent) {
        return (getV() + (getHeight() * precent)) / (float) getTexH();
    }

    //保存数据到nbt
    public void writeCustomDataToNbt(NbtCompound nbt) {
        NbtCompound textureElementData = new NbtCompound();
        textureElementData.putString("texture", getTexture().getPath());
        textureElementData.putInt("width", getWidth());
        textureElementData.putInt("height", getHeight());
        textureElementData.putInt("texW", getTexW());
        textureElementData.putInt("texH", getTexH());
        textureElementData.putInt("u", getU());
        textureElementData.putInt("v", getV());

        nbt.put("textureElement", textureElementData);
    }

    //从nbt读取数据
    public void readCustomDataFromNbt(NbtCompound nbt) {
        if (nbt.contains("textureElement")) {
            NbtCompound textureElementData = nbt.getCompound("textureElement");
            if (textureElementData.contains("width")) setWidth(textureElementData.getInt("width"));
            if (textureElementData.contains("height")) setHeight(textureElementData.getInt("height"));
            if (textureElementData.contains("texW")) setTexW(textureElementData.getInt("texW"));
            if (textureElementData.contains("texH")) setTexH(textureElementData.getInt("texH"));
            if (textureElementData.contains("u")) setU(textureElementData.getInt("u"));
            if (textureElementData.contains("v")) setV(textureElementData.getInt("v"));
        }
    }

    public Identifier getTexture() {
        return texture;
    }

    public void setTexture(Identifier texture) {
        this.texture = texture;
    }

    public int getWidth() {
        return width;
    }

    public void setWidth(int width) {
        this.width = width;
    }

    public int getHeight() {
        return height;
    }

    public void setHeight(int height) {
        this.height = height;
    }

    public int getTexW() {
        return texW;
    }

    public void setTexW(int texW) {
        this.texW = texW;
    }

    public int getTexH() {
        return texH;
    }

    public void setTexH(int texH) {
        this.texH = texH;
    }

    public int getColor() {
        return color;
    }

    public void setColor(int color) {
        this.color = color;
    }

    public int getU() {
        return u;
    }

    public void setU(int u) {
        this.u = u;
    }

    public int getV() {
        return v;
    }

    public void setV(int v) {
        this.v = v;
    }
}
